﻿using BCCommon;
using BCCommon.TMS.Transport;
using BCData.TMS.VehicleBusinessMapping;
using BCData.TMS.VehicleTransportBusinessConfig;
using BCDto.Sim.Admin.Admin;
using BCDto.TMS.Driver.VehicleBusiness;
using BCDto.TMS.VehicleBusinessMapping;
using BCEntity.Common.EntityNameConst;
using BCEntity.TMS.VehicleBusinessMapping;
using BCService.Common.Area;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;

namespace BCService.TMS.VehicleBusinessMappingOverwrite
{
    public class VehicleBusinessMappingOverwriteService : IVehicleBusinessMappingOverwriteService
    {
        private readonly IDatabaseContext databaseContext;
        private readonly IRedisService redisService;
        private readonly IVehicleBusinessMappingOverwriteData vehicleBusinessMappingOverwriteData;
        private readonly IVehicleBusinessMappingData vehicleBusinessMappingData;
        private readonly IVehicleTransportBusinessConfigData vehicleTransportBusinessConfigData;
        private readonly IZoneService zoneService;
        private readonly string key = string.Format("{0}", EntityNameConst.VehicleBusinessMappingOverwriteEntity);

        public VehicleBusinessMappingOverwriteService(IDatabaseContext databaseContext,
            IRedisService redisService,
            IVehicleBusinessMappingOverwriteData vehicleBusinessMappingOverwriteData,
            IVehicleBusinessMappingData vehicleBusinessMappingData,
            IVehicleTransportBusinessConfigData vehicleTransportBusinessConfigData,
            IZoneService zoneService)
        {
            this.databaseContext = databaseContext;
            this.redisService = redisService;
            this.vehicleBusinessMappingOverwriteData = vehicleBusinessMappingOverwriteData;
            this.vehicleBusinessMappingData = vehicleBusinessMappingData;
            this.vehicleTransportBusinessConfigData = vehicleTransportBusinessConfigData;
            this.zoneService = zoneService;
        }

        #region 检查车辆与业务配置重写是否存在
        public bool Exists(int vehicleBusinessMappingOverwriteId)
        {
            return this.vehicleBusinessMappingOverwriteData.Exists(vehicleBusinessMappingOverwriteId).GetAwaiter().GetResult();
        }
        #endregion

        #region 添加车辆与业务配置重写
        public VehicleBusinessMappingDto Add(AdminDto adminDto, VehicleBusinessMappingOverwriteDto requestDto)
        {
            if (adminDto.AgentRecord == null)
            {
                throw new ArgumentException("非代理商无需操作!");
            }

            if (!this.vehicleBusinessMappingData.Exists(requestDto.VehicleBusinessMappingId).GetAwaiter().GetResult())
            {
                throw new ArgumentException("此车辆业务配置不存在!");
            }
            if (this.vehicleBusinessMappingOverwriteData.Exists(adminDto.AgentRecord.AgentRecordId, requestDto.CountyCode, requestDto.VehicleBusinessMappingId).GetAwaiter().GetResult())
            {
                throw new ArgumentException("此区域的车辆业务配置信息已存在!");
            }
            var zoneEntity = this.zoneService.GetFromZoneEntity(requestDto.CountyCode);
            if (zoneEntity == null || zoneEntity.countyEntity == null || zoneEntity.provinceEntity == null || zoneEntity.cityEntity == null)
            {
                throw new ArgumentException("此区县编码不正确");
            }
            var entity = this.vehicleBusinessMappingData.GetEntity(requestDto.VehicleBusinessMappingId).GetAwaiter().GetResult();
            entity.CreateAdminName = adminDto.FullName;
            entity.CreateAdminId = adminDto.AdminId;
            entity.ProvinceCode = zoneEntity.provinceEntity.ProvinceCode;
            entity.CityCode = zoneEntity.cityEntity.CityCode;
            entity.CountyCode = zoneEntity.countyEntity.CountyCode;
            entity.AgentRecordId = adminDto.AgentRecord.AgentRecordId;

            return this.vehicleBusinessMappingOverwriteData.Add(entity).GetAwaiter().GetResult().As<VehicleBusinessMappingDto>();
        }
        #endregion

        #region 修改车辆与业务配置重写
        public VehicleBusinessMappingDto Update(AdminDto adminDto, VehicleBusinessMappingOverwriteDto putDto)
        {
            if (adminDto.AgentRecord == null)
            {
                throw new ArgumentException("非代理商无需操作!");
            }
            if (!putDto.VehicleBusinessMappingOverwriteId.HasValue)
            {
                throw new ArgumentException("区域的车辆业务配置信息Id不允许为空!");
            }
            if (!this.vehicleBusinessMappingData.Exists(putDto.VehicleBusinessMappingId).GetAwaiter().GetResult())
            {
                throw new ArgumentException("此车辆业务配置不存在!");
            }
            if (this.vehicleBusinessMappingOverwriteData.Exists(putDto.VehicleBusinessMappingOverwriteId.Value).GetAwaiter().GetResult())
            {
                throw new ArgumentException("此区域的车辆业务配置信息已存在!");
            }
            var zoneEntity = this.zoneService.GetFromZoneEntity(putDto.CountyCode);
            if (zoneEntity == null || zoneEntity.countyEntity == null || zoneEntity.provinceEntity == null || zoneEntity.cityEntity == null)
            {
                throw new ArgumentException("此区县编码不正确");
            }

            var entity = this.vehicleBusinessMappingOverwriteData.GetEntity(putDto.VehicleBusinessMappingOverwriteId.Value).GetAwaiter().GetResult();
            entity.EditAdminName = adminDto.FullName;
            entity.EditAdminId = adminDto.AdminId;
            entity.ProvinceCode = zoneEntity.provinceEntity.ProvinceCode;
            entity.CityCode = zoneEntity.cityEntity.CityCode;
            entity.CountyCode = zoneEntity.countyEntity.CountyCode;
            entity.AgentRecordId = adminDto.AgentRecord.AgentRecordId;
            var result = this.vehicleBusinessMappingOverwriteData.Update(entity).GetAwaiter().GetResult().As<VehicleBusinessMappingDto>();
            string cacheKey = this.redisService.GetKey(key, entity.VehicleBusinessMappingOverwriteId);
            this.redisService.DeleteAsync(cacheKey);
            return result;
        }
        #endregion

        #region 删除车辆与业务配置重写
        public bool Delete(AdminDto adminDto, int vehicleBusinessMappingOverwriteId)
        {
            if (!this.Exists(vehicleBusinessMappingOverwriteId))
            {
                throw new ArgumentException("此记录不存在!");
            }
            var entity = this.Get(vehicleBusinessMappingOverwriteId);
            if (entity.AgentRecordId != adminDto.AgentRecord.AgentRecordId)
            {
                throw new ArgumentException("您无权删除此配置!");
            }
            var result = this.vehicleBusinessMappingOverwriteData.Delete(vehicleBusinessMappingOverwriteId).GetAwaiter().GetResult();
            string cacheKey = this.redisService.GetKey(key, vehicleBusinessMappingOverwriteId);
            this.redisService.DeleteAsync(cacheKey);
            return result;
        }
        #endregion

        #region 获取车辆与业务配置重写
        public VehicleBusinessMappingDto Get(int vehicleBusinessMappingOverwriteId)
        {
            string cacheKey = this.redisService.GetKey(key, vehicleBusinessMappingOverwriteId);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.vehicleBusinessMappingOverwriteData.GetEntity(vehicleBusinessMappingOverwriteId).GetAwaiter().GetResult();
                return data;
            }, TimeSpan.FromDays(1));
            return result.As<VehicleBusinessMappingDto>();
        }

        public VehicleBusinessMappingDto Get(int vehicleBusinessMappingId, long agentRecordId)
        {
            string cacheKey = this.redisService.GetKey(key, vehicleBusinessMappingId, agentRecordId);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.vehicleBusinessMappingOverwriteData.GetEntity(vehicleBusinessMappingId, agentRecordId).GetAwaiter().GetResult();
                return data;
            }, TimeSpan.FromDays(1));
            return result.As<VehicleBusinessMappingDto>();
        }

        public VehicleBusinessMappingDto Get(TransportBusinessType transportBusinessType, int vehicleTypeId, int? vehicleCategoryReferenceId, long agentRecordId)
        {
            string cacheKey = this.redisService.GetKey(key, transportBusinessType, vehicleTypeId, vehicleCategoryReferenceId, agentRecordId);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.vehicleBusinessMappingOverwriteData.GetEntity(transportBusinessType, vehicleTypeId, vehicleCategoryReferenceId, agentRecordId).GetAwaiter().GetResult();
                return data;
            }, TimeSpan.FromDays(1));
            return result.As<VehicleBusinessMappingDto>();
        }
        #endregion

        #region 获取车辆与业务配置重写列表
        public IEnumerable<VehicleBusinessMappingDto> GetList(AdminDto adminDto)
        {
            string cacheKey = this.redisService.GetKey(key, adminDto.AgentRecord.AgentRecordId);
            var result = this.redisService.TryGet(key, () =>
            {
                var list = this.vehicleBusinessMappingData.GetList().GetAwaiter().GetResult();
                var overwrite = this.vehicleBusinessMappingOverwriteData.GetList(adminDto.AgentRecord.AgentRecordId).GetAwaiter().GetResult();
                List<VehicleBusinessMappingEntity> resultList = new List<VehicleBusinessMappingEntity>();
                foreach (var item in list)
                {
                    if (overwrite.Any(p => p.VehicleBusinessMappingId.Equals(item.VehicleBusinessMappingId)))
                    {
                        var overwriteItem = overwrite.Single(p => p.VehicleBusinessMappingId.Equals(item.VehicleBusinessMappingId));
                        if (overwriteItem.Enabled)
                        {
                            resultList.Add(overwriteItem);
                        }
                    }
                    else
                    {
                        resultList.Add(item);
                    }
                }
                return resultList;
            }, TimeSpan.FromDays(1));
            return result.As<IEnumerable<VehicleBusinessMappingDto>>();
        }
        public IEnumerable<VehicleBusinessMappingDto> GetList(string countyCode)
        {
            string cacheKey = this.redisService.GetKey(key, countyCode);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var list = this.vehicleBusinessMappingData.GetList().GetAwaiter().GetResult();
                var overwrite = this.vehicleBusinessMappingOverwriteData.GetList(countyCode).GetAwaiter().GetResult();
                List<VehicleBusinessMappingEntity> resultList = new List<VehicleBusinessMappingEntity>();
                foreach (var item in list)
                {
                    if (overwrite.Any(p => p.VehicleBusinessMappingId.Equals(item.VehicleBusinessMappingId)))
                    {
                        var overwriteItem = overwrite.Single(p => p.VehicleBusinessMappingId.Equals(item.VehicleBusinessMappingId));
                        if (overwriteItem.Enabled)
                        {
                            resultList.Add(overwriteItem);
                        }
                    }
                    else
                    {
                        resultList.Add(item);
                    }
                }
                return resultList;
            }, TimeSpan.FromDays(365));
            return result.As<IEnumerable<VehicleBusinessMappingDto>>();
        }
        #endregion

        #region 获取车辆与业务配置重写分页
        public PageableList<VehicleBusinessMappingDto> Query(long? agentRecordId, string provinceCode, string cityCode, string countyCode, int? vehicleTransportBusinessConfigId, int? vehicleTypeId, bool? enabled, DateTime? start, DateTime? end, string sortName, bool? ascending, int pageIndex, int pageSize)
        {
            string cacheKey = this.redisService.GetKey(key, agentRecordId, provinceCode, cityCode, countyCode, vehicleTransportBusinessConfigId, vehicleTypeId, enabled, start, end, sortName, ascending, pageIndex, pageSize);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.vehicleBusinessMappingOverwriteData.Query(agentRecordId, provinceCode, cityCode, countyCode, vehicleTransportBusinessConfigId, vehicleTypeId, enabled, start, end, sortName, ascending, pageIndex, pageSize).GetAwaiter().GetResult();
                return new PageableList<VehicleBusinessMappingDto>
                {
                    Count = data.Item2,
                    Items = data.Item1.As<IEnumerable<VehicleBusinessMappingDto>>(),
                    PageIndex = pageIndex,
                    PageSize = pageSize,
                    ServerTime = DateTime.Now
                };
            }, TimeSpan.FromMinutes(30));

            return result;
        }
        #endregion

        #region 启用车辆与业务配置重写
        public bool Enabled(AdminDto adminDto, int vehicleBusinessMappingOverwriteId)
        {

            if (adminDto.AgentRecord == null)
            {
                throw new ArgumentException("非代理商无权修改此配置!");
            }
            if (!this.Exists(vehicleBusinessMappingOverwriteId))
            {
                throw new ArgumentException("此记录不存在!");
            }
            var entity = this.Get(vehicleBusinessMappingOverwriteId);
            if (entity.AgentRecordId != adminDto.AgentRecord.AgentRecordId)
            {
                throw new ArgumentException("您无权修改此配置!");
            }
            var result = this.vehicleBusinessMappingOverwriteData.Enabled(vehicleBusinessMappingOverwriteId, adminDto.AdminId, adminDto.FullName).GetAwaiter().GetResult();
            string cacheKey = this.redisService.GetKey(key, vehicleBusinessMappingOverwriteId);
            this.redisService.DeleteAsync(cacheKey);
            return result;
        }
        #endregion

        #region 禁用车辆与业务配置重写
        public bool Disabled(AdminDto adminDto, int vehicleBusinessMappingOverwriteId)
        {

            if (adminDto.AgentRecord == null)
            {
                throw new ArgumentException("非代理商无权修改此配置!");
            }
            if (!this.Exists(vehicleBusinessMappingOverwriteId))
            {
                throw new ArgumentException("此记录不存在!");
            }
            var entity = this.Get(vehicleBusinessMappingOverwriteId);
            if (entity.AgentRecordId != adminDto.AgentRecord.AgentRecordId)
            {
                throw new ArgumentException("您无权修改此配置!");
            }
            var result = this.vehicleBusinessMappingOverwriteData.Disabled(vehicleBusinessMappingOverwriteId, adminDto.AdminId, adminDto.FullName).GetAwaiter().GetResult();
            string cacheKey = this.redisService.GetKey(key, vehicleBusinessMappingOverwriteId);
            this.redisService.DeleteAsync(cacheKey);
            return result;
        }


        #endregion

        #region 获取运输车辆列表
        public IEnumerable<VehicleBusinessMappingForAppDto> GetDistinctList(string countyCode)
        {
            string cacheKey = this.redisService.GetKey(key, countyCode);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var list = this.vehicleBusinessMappingData.GetListForApp().GetAwaiter().GetResult();
                var overwrite = this.vehicleBusinessMappingOverwriteData.GetListForApp(countyCode).GetAwaiter().GetResult().GroupBy(p => new { p.TransportBusiness, p.VehicleTypeId, p.CountyCode }).ToList();
                List<VehicleBusinessMappingForAppEntity> resultList = new List<VehicleBusinessMappingForAppEntity>();
                foreach (var item in list)
                {
                    if (overwrite.Any(p => p.First().VehicleBusinessMappingId.Equals(item.VehicleBusinessMappingId)))
                    {
                        var overwriteItem = overwrite.Single(p => p.First().VehicleBusinessMappingId.Equals(item.VehicleBusinessMappingId));
                        if (overwriteItem.First().Enabled)
                        {
                            resultList.Add(overwriteItem.First());
                        }
                    }
                    else
                    {
                        resultList.Add(item);
                    }
                }
                return resultList;
            }, TimeSpan.FromDays(365));
            return result.As<IEnumerable<VehicleBusinessMappingForAppDto>>();
        }
        #endregion


    }
}